package analysis;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javatools.PlingStemmer;

import net.didion.jwnl.JWNL;
import net.didion.jwnl.JWNLException;
import net.didion.jwnl.data.IndexWord;
import net.didion.jwnl.data.POS;

import opennlp.tools.lang.english.PosTagger;
import opennlp.tools.postag.POSDictionary;

public class Analyzer {
	
	private static PosTagger tagger;
	private static net.didion.jwnl.dictionary.Dictionary dict;
	private static ArrayList<String> fwdict;
	
	/******************************/

	private static void createTagger () {
		//CREA EL TAGGER PARA ETIQUETAR LAS PALABRAS
		try {
			//C:/Users/Carmo/ecplise_workspace/MyLittleTrivial2/
			tagger = new PosTagger("./res/tagger/tag.bin.gz",
					new POSDictionary("./res/tagger/tagdict", true));
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("Cannot create tagger");
		}
	}
	
	/******************************/
	
	private static void createDict () {
		//CREA EL DICCIONARIO NORMAL EN EL QUE SE BUSCARAN INFINITIVOS DE VERBOS
		try {
			String properties = "./res/ontologies/wordnet/file_properties.xml";
			File file = new File(properties);
			try {
				JWNL.initialize(new FileInputStream(file));
			} catch (FileNotFoundException e) {
				System.out.println("PROPERTIES.XML FILE ERROR");
				e.printStackTrace();
			}
		} catch (JWNLException e) {
			e.printStackTrace();
			System.out.println("CANNOT CREATE");
		}
		dict = net.didion.jwnl.dictionary.Dictionary.getInstance();
	}
	
	/******************************/
	
	private static boolean createFWDict() {
		//CREA LA LISTA DE STOPWORDS
		fwdict = new ArrayList<String>();
		String fileName = "./res/indices/MY_STOPWORDS";
		try {
			if (fileName != null) {
				File file = new File(fileName);
				BufferedReader in = new BufferedReader(new FileReader(file));
				String word;
				String term;
				
				while ((word = in.readLine()) != null)  {
					// read and normalize word
					term = word.trim();
					if (term.startsWith("//")) continue;  // skip comments
					term = term.toLowerCase();
					
					// add whole word
					if (term.length() > 0)
						if (!fwdict.contains(term)) {
							//System.out.println(term);
							fwdict.add(term);
						}
				}

				in.close();
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("FWDict: cannot open file");
			return false;
		}
		
		return true;
	}
	
	/******************************/
	
	public static boolean initialize() {
		//INICIALIZA EL TAGGER Y LOS DICCIONARIOS (LLAMADO AL PRINCIPIO DE MAIN)
		createTagger();
		createDict();
		createFWDict();
		
		return true;
	}
	
	/******************************/
	/* METODOS AUXILIARES TAGGER */
	
	public static String[] protag (String[] words) {
		//UTILIZA EL TAGGER "PROFESIONAL"
		return tagger.tag(words);
	}
	
	public static String[] retag (String[] words, String[] originaltags) {
		/*CAMBIA AQUELLAS ETIQUETAS QUE POR CUALQUIER MOTIVO EL TAGGER NO
		ETIQUETE BIEN */
		String[] tags = originaltags;
		
		for (int i = 0; i < originaltags.length; i++) {
			if (words[i].endsWith("ing"))
				if (originaltags[i+1].startsWith("NN"))
					tags[i] = "JJ";
		}
		return tags;
	}
	
	/******************************/
	/* METODOS AUXILIARES DICCIONARIO NORMAL */
	
	public static String getLemma (String word, POS pos) {
		//BUSCA LA FORMA NORMAL DE UNA PALABRA EN DICT
		if (dict == null) {
			System.out.println("NO DICT");
			return null;
		}
		
		IndexWord indexWord = null;
		try {
			indexWord = dict.lookupIndexWord(POS.VERB, word);
		} catch (JWNLException e) {}
		if (indexWord == null) return null;
		
		String lemma = indexWord.getLemma();
		lemma = lemma.replace("_", " ");
		
		return lemma;
	}
	
	/******************************/
	
	public static String stem (String[] words, String[] tags, String original) {
		//STEMIZADO DE PALABRAS EN FUNCION DE SU ETIQUETA
		String newstring = original;
		for (int i = 0; i < words.length; i++) {
			if (tags[i].startsWith("VB")) {
				String rep = getLemma(words[i], POS.VERB);
				if (rep == null) rep = words[i];
				newstring = newstring.replace(words[i], rep);
			} else if (tags[i].startsWith("NN")) {
				String rep = PlingStemmer.stem(words[i]);
				newstring = newstring.replace(words[i], rep);
			}
		}
		return newstring;
		
	}
	
	/******************************/
	/* METODOS ELIMINACION PALABRAS INNECESARIAS */
	
	public static String[] dropSingleChars (String[] original) {
		//QUITA PALABRAS DE UN SOLO CARACTER
		ArrayList<String> noChar = new ArrayList<String>();
		
		for (String word : original)
			if (word.length() > 1) noChar.add(word);
		
		return noChar.toArray(new String[noChar.size()]);
	}
	
	/******************************/
	
	public static String[] dropBadKeywords (String[] original) {
		//QUITA PALABRAS QUE NO APORTAN SIGNIFICADO
		
		String IGNORE = "(names?|give|tell|list)";
		
		ArrayList<String> goodKeywords = new ArrayList<String>();
		
		for (String word : original)
			if (!word.matches("(?i)" + IGNORE)) goodKeywords.add(word);
		
		return goodKeywords.toArray(new String[goodKeywords.size()]);
	}
	
	/******************************/
	
	public static boolean functionWordLookup (String word) {
		//BUSCA SI UNA PALABRA ES UNA STOPWORD
		return (fwdict.contains(word.toLowerCase()));
	}
	
	/******************************/
	
	public static String[] dropFunctionWords (String[] original) {
		//ELIMINA LAS STOPWORDS

		ArrayList<String> content = new ArrayList<String>();
		
		for (int i = 0; i < original.length; i++) {
			if (!functionWordLookup(original[i])) {
				content.add(original[i]);
			}
		}
		return content.toArray(new String[content.size()]);
	}
	
	/******************************/
	
	public static String[] dropDuplicates (String[] original) {
		//ELIMINA PALABRAS DUPLICADAS
		ArrayList<String> wordList = new ArrayList<String>();
		
		for (int i = 0; i < original.length; i++) {
			if (!wordList.contains(original[i])) {
				wordList.add(original[i]);
			}
		}
		
		return wordList.toArray(new String[wordList.size()]);
		
	}
	
	/******************************/
	
	public static String[] getWords (String phrase) {
		String[] chunked = phrase.split(" ");
		
		return chunked;
	}
	
}
